package collector;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import parser.CodeReviewToken;

/**
 * @author dotekien
 * @author brianegge
 *         Date: Mar 13, 2006
 *         Time: 5:31:36 PM
 */
public class FileObj {
    private File file;
    private int numberOfWarningStatement = 0;
    private ArrayList<Statement> statements;   //array statement
    private ArrayList<Chunk> chunks;   //chunks are duplicated somewhere and each chunk is unique

    private ArrayList<CodeReviewToken> tokens;   //contain all tokens used for decorate-text
    public int lineCount;

    public FileObj(File file) {
        this.file = file;
        statements = new ArrayList<Statement>();
        chunks = new ArrayList<Chunk>();
        tokens = new ArrayList<CodeReviewToken>();
    }

    public String getName() {
        try {
            return file.getCanonicalPath();
        } catch (IOException e) {
            return file.getName();
        }
    }

    public String getPath() {
        try {
            return file.getCanonicalPath();
        } catch (IOException e) {
            System.err.println("Cannot get the absolute path of" + getName());
            System.exit(1);
        }
        return "";
    }

    public File getFile() {
        return file;
    }

//    public void setFile(File file) {
//        this.file = file;
//    }

    public int getNumberOfWarningStatement() {
        return numberOfWarningStatement;
    }

//    public double getPercentageOfDuplication() {
//        return percentageOfDuplication;
//    }

//    public void setPercentageOfDuplication(double percentageOfDuplication) {
//        this.percentageOfDuplication = percentageOfDuplication;
//    }

    public int getNumberOfStatement() {
        return statements.size();
    }

    public Statement getStatement(int i) {
        return statements.get(i);
    }

    public void addStatement(Statement s) {
        statements.add(s);
    }

    public ArrayList<Chunk> getChunks() {
        return chunks;
    }

    public void addChunk(Chunk chunk, int length) {
        chunks.add(chunk);
        numberOfWarningStatement += length;
    }

//    public Token getToken(int i) {
//        return tokens.get(i);
//    }

    public void addToken(CodeReviewToken token) {
        token.setId(tokens.size());
        tokens.add(token);
    }

    public ArrayList<CodeReviewToken> getTokens() {
        return tokens;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append(getName());
//        try{
//            sb.append(file.getCanonicalPath() + ";");
//        }catch (IOException e) {}
//        sb.append(getNumberOfStatement() + ";");
//        sb.append(numberOfPhysicLine + ";");
//        sb.append(numberOfWarningStatement + ";");
//        sb.append(percentageOfDuplication + ";");
        //sb.append(statements + ";");
        //sb.append(chunks + ";");
        return sb.toString().intern();
    }

    public String getStatements() {
        StringBuffer sb = new StringBuffer();
        for (Statement statement : statements) {
            sb.append(statement).append(Configuration.EOL);
        }
        return sb.toString().intern();
    }

    public String getSource(int lineStart, int lineEnd) throws IOException {
        FileInputStream in = new FileInputStream(file);
        InputStreamReader reader = new InputStreamReader(in);
        BufferedReader buf = new BufferedReader(reader);
        StringBuffer sb = new StringBuffer();
        int line = 1;
        for (String s = ""; s != null; line++) {
            s = buf.readLine();
            if (line >= lineStart && line < lineEnd) {
                sb.append(s).append("\n");
            }
        }
        buf.close();
        reader.close();
        in.close();
        return sb.toString().intern();
    }

    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final FileObj obj = (FileObj) o;

        return !(file != null ? !file.equals(obj.file) : obj.file != null);
    }

    public int hashCode() {
        return file != null ? file.hashCode() : 0;
    }
}
